package com.foo.designpattern.adapter;

import junit.framework.TestCase;

/**
 * com.foo.designpattern.adapter
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-05-16 17:22.
 *
 * @Description 测试类：适配器模式(Adapter1)
 * 适配器模式把一个类的接口转换成客户端所期待的另一种接口，从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
 * <p/>
 * 适配器模式的结构：适配器模式有类的适配器、对象的适配器模式和接口的适配器模式三种不同的形式。
 * <p/>
 * 1、类的适配器模式的核心思想：
 * 有一个Adaptee类(本例有两个Adapter1,Adapter2)，拥有一个方法(分别为request1,request2)，待适配，
 * 目标接口是Target，通过Adapter类(分别为Adapter1,Adapter2)，将Adaptee的功能扩展到Target里，
 * Adapter类继承Adaptee类，实现Target接口，这样，Target接口的实现类就具有了Adaptee类的功能。
 * 本例是类的适配器模式。
 * 2、对象的适配器模式：
 * 基本思路和类的适配器模式相同，只是将Adapter类稍作修改，不继承Adaptee类，而是持有Adaptee类的实例，以达到解决兼容性的问题。
 * 3、接口的适配器模式：
 * 接口的适配器是这样的：有时我们写的一个接口中有多个抽象方法，当我们写该接口的实现类时，必须实现该接口的所有方法，这有时是比较浪费的，
 * 因为并不是所有的方法都是我们需要的，有时只需要某一个或者某一些，此处为了解决这个问题，我们引入接口的适配器模式，借助于一个抽象类，
 * 该抽象类实现了该接口，实现了所有的方法，而我们不和原始的接口打交道，只和该抽象类取得联系，
 * 所有我们写一个类，继承该抽象类，重写我们需要的方法就行。
 * <p/>
 * 适配器模式所涉及的角色有：
 * 1、目标(Target)角色：这就是所期待得到的接口。注意：由于本例是类的适配器模式，因为目标不可以是类，这里是接口(interface)。
 * 2、源(Adaptee)角色：现在需要适配的接口。
 * 3、适配器(Adapter)角色：适配器是本模式的核心。适配器把源接口转换成目标接口。
 * <p/>
 * 适配器模式的应用场景：
 * 1、类的适配器模式：当希望将一个类转换成满足另一个新接口的类时，可以使用类的适配器模式，
 * 【注意：创建一个新类，继承原有的类】，实现新的接口即可。
 * 2、对象的适配器模式：当希望将一个对象转换成满足另一个新接口的对象时，可以创建一个Wrapper类，
 * 【注意：持有原类的一个实例】，在Wrapper类的方法中，调用实例的方法就行。
 * 3、接口的适配器模式：当不希望实现一个接口中所有的方法时，可以创建一个抽象类Wrapper，
 * 【注意：实现所有方法】，我们写别的类的时候，继承抽象类即可。
 */

public class AdapterTestCase extends TestCase {
    public void testAdapter() {
        System.out.println("= = = = ↓↓↓适配器模式，测试开始↓↓↓ = = = =");
        Target target1 = new Adapter1();
        // 适配之后，将Adaptee的功能扩展到Target里
        target1.Request1();
        target1.Request2();
        target1.Request3();
        Target target2 = new Adapter2();
        // 适配之后，将Adaptee的功能扩展到Target里
        target2.Request1();
        target2.Request2();
        target2.Request3();
        System.out.println("= = = = ↑↑↑适配器模式，测试结束↑↑↑ = = = =");
    }
}
